package com.zx.security.block.service.impl;

import com.zx.core.constant.TokenConstants;
import com.zx.redis.block.service.RedisBlockService;
import com.zx.security.block.service.ICustomTokenService;
import com.zx.security.common.model.LoginUser;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * <p>
 * description: token验证处理实现 <br>
 * create: 2025-05-06 10:50
 * </p>
 *
 * @author zhou  xun
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CustomTokenServiceImpl implements ICustomTokenService {

    private final RedisBlockService redisBlockService;

    private final JwtDecoder jwtDecoder;

    /**
     * 获取用户身份信息
     *
     * @param token 令牌
     * @return {@link LoginUser}
     * @author zhou  xun
     * @since 2025-05-06
     */
    @Override
    public LoginUser getLoginUser(String token) {
        if (!StringUtils.hasLength(token)) {
            return null;
        }
        try {
            Jwt jwt = jwtDecoder.decode(token);
            if (jwt == null) {
                throw new RuntimeException("JWT 解码失败：无效或格式错误的 token");
            }
            // 直接使用 Jwt 的 getClaim() 方法获取声明
            String userId = jwt.getClaim("userId");
            //空判断uuid
            if (!StringUtils.hasLength(userId)) {
                log.error("JWT 缺少 userId 声明");
                throw new RuntimeException("JWT 缺少 userId 声明");
            }

            String cacheKey = TokenConstants.REDIS_LOGIN_KEY_PREFIX + userId;
            // 从Redis获取缓存的用户信息
            LoginUser loginUser = redisBlockService.getCachedObject(cacheKey, LoginUser.class);

            if (loginUser == null) {
                log.error("Redis中不存在对应的用户信息，键为: {}", cacheKey);
                throw new RuntimeException("Redis中不存在对应的用户信息");
            }
            return loginUser;
        } catch (Exception e) {
            log.error("获取用户信息异常", e);
            return null;
        }
    }

    /**
     * 获取JWT解码器
     *
     * @return {@link JwtDecoder}
     */
    @Override
    public JwtDecoder getJwtDecoder() {
        return jwtDecoder;
    }

    /**
     * 删除用户身份信息
     *
     * @param token 令牌
     * @author zhou  xun
     * @since 2025-05-06
     */
    @Override
    public void delLoginUser(String token) {
        if (!StringUtils.hasLength(token)) {
            throw new IllegalArgumentException("无效的令牌");
        }
        Jwt jwt = jwtDecoder.decode(token);
        // 直接使用 Jwt 的 getClaim() 方法获取声明
        String userId = jwt.getClaim("userId");
        if (!StringUtils.hasLength(userId)) {
            throw new IllegalArgumentException("无效的用户标识");
        }
        String redisKey = TokenConstants.REDIS_LOGIN_KEY_PREFIX + userId;
        redisBlockService.deleteObject(redisKey);
    }
}